
function init() {
	dump_line("version 2010-12-22 22:39");
}

var modules = [];

var ports = {
	add: {
		fixed: {
			input: [],
			output: ['out']
		},
		variable: {
			input: ['in'],
			output: []
		}
	},
	cos: {
		fixed: {
			input: ['in'],
			output: ['out']
		}
	},
	cossegs: {
		fixed: {
			input: ['in'],
			output: ['out']
		},
		variable: {
			input: ['value', 'duration'],
			output: []
		}
	},
	cpsoct: {
		fixed: {
			input: ['in'],
			output: ['out']
		}
	},
	delay: {
		fixed: {
			input: ['in'],
			output: []
		},
		variable: {
			input: ['time'],
			output: ['tap']
		}
	},
	trigger: {
		fixed: {
			input: ['in'],
			output: ['out']
		},
		variable: {
			input: ['threshold'],
			output: ['out']
		},
		options: {
			mode: ['up', 'wrapup', 'down', 'wrapdown', 'both']
		}
	}
};

var module_types = [
	'add', 'cos', 'cossegs', 'cpsoct', 'delay',
	'linsegs', 'mult', 'noise', 'phasor', 'proc',
	'randcos', 'randh', 'randlin', 'seq', 'sh',
	'shortout', 'stereopan', 'trigger'
];

var next_id = 0;

function new_module() {
	modules.push(empty_module());
	draw_modules();
}

function draw_modules() {
	var i = 0;
	var s = '';
	for (i = 0; i < modules.length; ++i) {
		s += draw_module(modules[i]);
	}
	var d = document.getElementById('modules');
	d.innerHTML = s;
}

function draw_module(m) {
	return "<div id='module_" + m.id + "' style='background-color: white; color:blue;'>" + draw_module_moves(m) + m.id + draw_module_type_menu(m) + draw_module_inserts(m) + draw_ports_fixed(m) + draw_ports_variable(m) + "</div>";
}

function draw_fixed_inputs(m) {
	try {
		var a = ports[m.type].fixed.input;
		var s = '';
		var i;
		for (i = 0; i < a.length; ++i) {
			s += '<input type="button" style="background-color:green;" value="' + a[i] + '">';
		}
		return s;
	} catch (e) {
		return '';
	}
}

function draw_fixed_outputs(m) {
	try {
		var a = ports[m.type].fixed.output;
		var s = '';
		var i;
		for (i = 0; i < a.length; ++i) {
			s += '<input type="button" style="background-color:red;" value="' + a[i] + '">';
		}
		return s;
	} catch (e) {
		return '';
	}
}

function draw_ports_fixed(m) {
	return '<div style="background-color: gray; color: black"> ' + draw_fixed_inputs(m) + ' | ' + draw_fixed_outputs(m) + ' </div>';
}

function draw_ports_variable(m) {
	return '<div style="background-color: black; color: white">&nbsp;</div>';
}

function draw_module_inserts(m) {
	return '<input type="button" onclick="insert_module(' + m.id + ')" value="+">' +
	'<input type="button" onclick="delete_module(' + m.id + ')" value="-">';
}

function draw_module_moves(m) {
	return '<input type="button" onclick="move_module_up(' + m.id + ')" value="/\\">' +
	'<input type="button" onclick="move_module_down(' + m.id + ')" value="\\/">';
}

function move_module_up(k) {
	var i = find_module_index(k);
	if (0 >= i) { return; }
	if (-1 == i) { return; }
	var m = modules[i];
	modules[i] = modules[i - 1];
	modules[i - 1] = m;
	draw_modules();
}

function move_module_down(k) {
	var i = find_module_index(k);
	if ((modules.length - 1) <= i) { return; }
	if (-1 == i) { return; }
	var m = modules[i];
	modules[i] = modules[i + 1];
	modules[i + 1] = m;
	draw_modules();
}

function insert_module(k) {
	//alert("insert module before " + k);
	var m = empty_module();
	var i = find_module_index(k);
	if (-1 == i) { modules.push(m); }
	else {modules.splice(i, 0, m); }
	draw_modules();
}

function delete_module(k) {
	var i = find_module_index(k);
	if (-1 != i) {
		var a = modules.splice(i, 1);
		free_modules(a);
	}
	draw_modules();
}

function free_modules(a) {
	for (var i in a) { free_module(a[i]); }
}

function free_module(m) {
	//alert('deleting ' + m.id);
}

function find_module_index(k) {
	var i;
	for (i = 0; i < modules.length; ++i) {
		if (k == modules[i].id) { return i; }
	}
	return -1;
}

function find_module(k) {
	var i = find_module_index(k);
	if (-1 == i) {return {id: k};}
	return modules[i];
}

function choose_module_type(i) {
	var m = document.getElementById("module_" + i + "_type");
	if (-1 != module_types.indexOf(m.value)) { 
		find_module(i).type = m.value;
	}
	draw_modules();
}

function draw_module_type_menu(m) {
	var s = '<select id="module_' + m.id + '_type" onchange="choose_module_type(' + m.id + ')"><option></option>';
	var i;
	for (i = 0; i < module_types.length; ++i) {
		s += '<option ' + 
			((m.type == module_types[i]) ? 'selected ' : '' ) + 
			'value="'+ module_types[i] +'">' + 
			module_types[i] +'</option>';
	}
	s += '</select>';
	return s;
}

function empty_module() {
	return {id: ++next_id};
}

function dump_line(s) {
	queue_command(["log", s])
	return;
}

function play() {
	queue_command(["play"]);
}

function pause() {
	queue_command(["pause"]);
}

function stop() {
	queue_command(["stop"]);
}

function rel(n) {
	wave(n * 480);
}

function test() {
	queue_command(["stop"]);
	var a = ["parse"];

	a.push("module phasor ap");
	a.push("module cos af");
	a.push("module proc ar");

	a.push("module phasor pr");
	a.push("module randlin r");
	a.push("init r count 7");

	a.push("module cpsoct f1");
	a.push("module phasor p1");
	a.push("module cossegs w1");
	a.push("init w1 count 2");

	a.push("module cpsoct f2");
	a.push("module phasor p2");
	a.push("module cossegs w2");
	a.push("init w2 count 2");

	a.push("module cpsoct fr");

	a.push("module linsegs e1");
	a.push("init e1 count 3");
	a.push("module proc a1")

//	a.push("module cpsoct dt1")
	a.push("module cpsoct da1")
	a.push("module delay d1")
	a.push("init d1 count 1")
	a.push("module mult m1")
	a.push("init m1 count 2")
	a.push("module add dm1")
	a.push("init dm1 count 2")

//	a.push("module cpsoct dt2")
	a.push("module cpsoct da2")
	a.push("module delay d2")
	a.push("init d2 count 1")
	a.push("module mult m2")
	a.push("init m2 count 2")
	a.push("module add dm2")
	a.push("init dm2 count 2")

	a.push("module linsegs e2");
	a.push("init e2 count 3");
	a.push("module proc a2")

	a.push("module shortout o");
	a.push("init o count 2");

	a.push("patch ap:frequency " + 1/60);
	a.push("patch af:in ap:out");
	a.push("patch ar:amp 4");
	a.push("patch ar:off 4");
	a.push("patch ar:in af:out");

	a.push("patch fr:center ar:out");
	a.push("patch fr:in r:6");
	a.push("patch pr:frequency fr:out");
	a.push("patch r:in pr:out");

	a.push("patch f1:center 240");
	a.push("patch f1:in r:1");
	a.push("patch p1:frequency f1:out");
	a.push("patch w1:in p1:out");
	a.push("patch w1:1 -.5");
	a.push("patch w1:2 r:11");
	a.push("patch w1:3 .5");
	a.push("patch w1:4 pr:out");

	a.push("patch e1:in pr:out");
	a.push("patch e1:1 0");
	a.push("patch e1:2 r:8");
	a.push("patch e1:3 .5");
	a.push("patch e1:4 r:10");
	a.push("patch e1:5 0");
	a.push("patch e1:6 1");

	a.push("patch a1:amp e1:out");
	a.push("patch a1:in w1:out");
	a.push("patch dm1:1 a1:out");
	a.push("patch d1:in dm1:out");
//	a.push("patch dt1:center .25");
//	a.push("patch dt1:in r:11");
	a.push("patch da1:center .25");
	a.push("patch da1:in r:14");
	a.push("patch d1:1 .5");
	a.push("patch m1:1 d1:1");
	a.push("patch m1:2 da1:out");
	a.push("patch dm1:2 m1:out");

	a.push("patch e2:in pr:out");
	a.push("patch e2:1 0");
	a.push("patch e2:2 r:8");
	a.push("patch e2:3 .5");
	a.push("patch e2:4 r:10");
	a.push("patch e2:5 0");
	a.push("patch e2:6 1");

	a.push("patch a2:amp e2:out");
	a.push("patch a2:in w2:out");
	a.push("patch dm2:1 a2:out");
	a.push("patch d2:in dm2:out");
//	a.push("patch dt2:center .25");
//	a.push("patch dt2:in r:11");
	a.push("patch da2:center .25");
	a.push("patch da2:in r:14");
	a.push("patch d2:1 .5");
	a.push("patch m2:1 d2:1");
	a.push("patch m2:2 da2:out");
	a.push("patch dm2:2 m2:out");

	a.push("patch f2:center 240");
	a.push("patch f2:in r:3");
	a.push("patch p2:frequency f2:out");
	a.push("patch w2:in p2:out");
	a.push("patch w2:1 -.5");
	a.push("patch w2:2 r:11");
	a.push("patch w2:3 .5");
	a.push("patch w2:4 pr:out");

	a.push("patch o:1 dm1:out");
	a.push("patch o:2 dm2:out");

	queue_command(a);
	queue_command(["play"]);
}

function wave(f) {
	queue_command(["stop"]);
	var a = ["parse"];
	a.push(["module phasor p"]);
	a.push(["module cossegs w"]);

	a.push(["module phasor mp"]);
	a.push(["module cos mw"]);
	a.push(["module proc ma"]);

	a.push(["module mult m"]);

	a.push(["module shortout o"]);

	a.push(["init w count 2"]);
	a.push(["init m count 2"]);
	a.push(["init o count 1"]);

	a.push(["patch p:frequency " + f]);
	a.push(["patch w:in p:out"]);

	a.push(["patch mp:frequency 15"]);
	a.push(["patch mw:in mp:out"]);

	a.push(["patch w:1 -1"]);
	a.push(["patch w:2 ma:out"]);
	a.push(["patch w:3 1"]);
	a.push(["patch w:4 1"]);

	a.push(["patch ma:amp .5"]);
	a.push(["patch ma:off .5"]);
	a.push(["patch ma:in mw:out"]);

	a.push(["patch m:1 ma:out"]);
	a.push(["patch m:2 w:out"]);

	a.push(["patch o:1 m:out"]);

	queue_command(a);
	queue_command(["play"]);

}

function punch(s, f) {
	var a = s.split();
}

function escape_html(i) {

	if (null == i) { return ''; }
	var s = '' + i;
	return s.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;").split('"').join("&quot;").split("'").join("&apos;");

}
